package cn.com.cym.gamezao.jwt;

import cn.com.cym.gamezao.base.ResultResponse;
import cn.com.cym.gamezao.entity.authorize.User;
import cn.com.cym.gamezao.exception.BaseException;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.tomcat.util.codec.binary.Base64;
import org.apache.tomcat.util.codec.binary.StringUtils;
import org.springframework.http.HttpStatus;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JwtUtils
 */
public class JwtUtils {

    /**
     * 设置过期时间为5分钟
     */
    private final static long EXPIRE_TIME_MILLS=1000*60*5*60;

    /**
     * jwt 密钥
     */
    private static final String SECRET = "jwt_secret@Game";

    public static String create(User user) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);

            Map<String, Object> headerMap = new HashMap<String, Object>();
            headerMap.put("userName", user.getUserName());
            headerMap.put("where", user.getCurrentIp());
            boolean flag=user.getUserInfo()==null;
            long systemTimeMillis = System.currentTimeMillis() + EXPIRE_TIME_MILLS;
            String token = JWT.create().withHeader(headerMap)//可自定义传递参数
                    //.withIssuer("auth0")//签发者
                    .withIssuer("mr.chen")
                    .withIssuedAt(new Date())//签发时间
                    .withSubject("AUTH").withAudience(user.getUserName())
                    .withExpiresAt(new Date(systemTimeMillis))
                    .withJWTId(user.setSecret())
                    //payload中加入自定义数据
                    .withClaim("name",flag? null:user.getUserInfo().getNikeName()).withClaim("uniqueNo", user.setSecret())
                    .withClaim("expireTime",systemTimeMillis).sign(algorithm);
                   /* System.out.println("当前时间：" + new Date());
                    System.out.println("jwt token:" + token);*/
                    return token;
        } catch (JWTCreationException exception) {
            //Invalid Signing configuration / Couldn't convert Claims.
            throw exception;
        }
    }


    /**
     * 判断token是否过期
     * @return flag
     */
    public static Boolean  expire(String token){
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        JWTVerifier verifier = JWT.require(algorithm).build(); //Reusable verifier instance
        DecodedJWT jwt = verifier.verify(token);
        long expireTime = jwt.getClaim("expireTime").asLong();
        return System.currentTimeMillis()>expireTime;
    }

    public static Boolean verify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build(); //Reusable verifier instance
            DecodedJWT jwt = verifier.verify(token);
            //System.out.println(jwt);
            //System.out.println(jwt.getHeader());
            //System.out.println(jwt.getPayload());
            //System.out.println(jwt.getSignature());
           /* String decodeHeader = StringUtils.newStringUtf8(Base64.decodeBase64(jwt.getHeader()));


            String decodePayload = StringUtils.newStringUtf8(Base64.decodeBase64(jwt.getPayload()));

            String signature = jwt.getSignature();
            String name = jwt.getClaim("name").asString();
            String introduce = jwt.getClaim("introduce").asString();

            System.out.println("header:" + jwt.getHeader());
            System.out.println("payload:" + jwt.getPayload());
            System.out.println("signature:" + signature);

            System.out.println("headerString:" + decodeHeader);
            System.out.println("payloadString:" + decodePayload);

            System.out.println("name:" + name);
            System.out.println("introduce:" + introduce);*/
            return true;
        } catch (JWTVerificationException exception) {
            System.out.println("当前时间：" + new Date());
            System.out.println("验证token失败：" + exception.getMessage());
            throw new BaseException("认证过期，请重新登录",new ResultResponse("认证过期，请重新登录", HttpStatus.FORBIDDEN.value()));
            //return false;
        }
    }

    /**
     * 手动制token过期
     */
    //TODO
    public static void handleTokenExpire(String token){
        JWT.create().withExpiresAt(new Date());
    }

    public static void main(String[] args) throws InterruptedException {
        /*User user=new User();
        user.setUserName("cym1358723682");
        user.setPassword(MathUtils.sha("xayy@2021"));
        final String token = create(user);
        System.out.println(verify(token));
        Thread.sleep(20000L);

        System.out.println(verify(token));

        handleTokenExpire(token);*/

        verify("eyJ3aGVyZSI6IjA6MDowOjA6MDowOjA6MSIsInR5cCI6IkpXVCIsInVzZXJOYW1lIjoiY3ltMTM1ODcyMzY4MiIsImFsZyI6IkhTMjU2In0.eyJ1bmlxdWVObyI6Ijg3MjM2ODJhdXRoMDowOjA6MDowOjA6MDoxIiwic3ViIjoic3ViamVjdCIsImF1ZCI6IjEwMDEwMjEzNCIsIm5hbWUiOiJtci5jaGVuIiwiZXhwIjoxNjQ4MzQ1MDcxLCJpYXQiOjE2NDgzNDUwNjV9.uPwU2FGWPBmuDtlqYgElU0B3nMVN4Qwnj5f5BhwsTKQ");

    }
}
